/*
 * Credits goes to http://mobiforge.com/developing/story/sms-messaging-android
 */
package emt.friendtracking.smsmodule;

import java.text.SimpleDateFormat;
import java.util.Date;

import emt.friendtracking.BaseActivity;
import emt.friendtracking.Data;
import emt.friendtracking.DecryptionException;
import emt.friendtracking.IService;
import emt.friendtracking.MyApplication;
import emt.friendtracking.NotificationActivity;
import emt.friendtracking.R;
import emt.friendtracking.locationmodule.Coordinates;
import emt.friendtracking.locationmodule.CoordinatesHandler;
import emt.friendtracking.locationmodule.CoordinatesUpdateListener;
import emt.friendtracking.locationmodule.LocationIdentifier;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.RemoteViews;

/**
 * The source code, which this service is base on is available for download at: http://mobiforge.com/developing/story/sms-messaging-android
 */
public class SmsReceiverService extends BroadcastReceiver implements CoordinatesUpdateListener, IService
{
	private static final String TAG = SmsReceiverService.class.getSimpleName();

	ContentValues values = null;
	public static final String SMS_EXTRA_NAME = "pdus";
	private static boolean runningIsAllowed = true;

	private Message message = null;
	
	private static String MSG = "";

	public void onReceive( Context context, Intent intent )
	{
		Log.d(TAG, "onReceived."); //TODO "onReceived."
		if(runningIsAllowed)
		{
			runningIsAllowed = false;
			//quote: "The SMS message is contained and attached to the Intent object (intent --- ) via a Bundle object."
			Bundle extras = intent.getExtras();

			String encryptedData = "";

			if ( extras != null )
			{
				// Get the received SMS array (Which is the actual SMS saved in a PDU format). quote: "The messages are stored in an Object array in the PDU format"
				// The SMS may be a chained SMS (4 SMS's received as one SMS).
				Object[] smsExtra = (Object[]) extras.get( SMS_EXTRA_NAME );

				if(smsExtra.length==1)
				{
					Log.d(TAG, "Possible SMS received."); //TODO "Possible SMS received."

					SmsMessage sms = SmsMessage.createFromPdu((byte[])smsExtra[0]);
					
					String test = sms.getMessageBody().toString();
					
					if(test.equalsIgnoreCase(MSG))
					{
						runningIsAllowed = true;
						this.abortBroadcast();
					}
					else
					{
						MSG = test;
						encryptedData = MSG;
	
						try
						{
							message = Message.get(encryptedData);
							Log.d(TAG, "Encrypted information received."); //TODO "Encrypted information received."
	
							if(message.type!=null)
							{
								int icon = R.drawable.friendtracker_icon;
								CharSequence tickerText;
								long when = System.currentTimeMillis();
								CharSequence contentTitle = "FriendTracker";//Resources.getSystem().getString(R.string.app_name);
								CharSequence contentText;
								Notification theNotificationToShow;
								MyApplication.getAppContext();
								NotificationManager notificationManager = (NotificationManager) 
										MyApplication.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);
	
								Intent notificationIntent = new Intent();
								PendingIntent contentIntent = PendingIntent.getActivity(MyApplication.getAppContext(), 0, notificationIntent, 0);
	
								RemoteViews contentView = new RemoteViews(MyApplication.getAppContext().getPackageName(), R.layout.notify1);
								contentView.setImageViewResource(R.id.imageNotify, icon);
								contentView.setTextViewText(R.id.titleNotify, contentTitle);
	
	
								switch(message.type)
								{
									case ACCEPT:
										tickerText = "TrackingAccept";//Resources.getSystem().getString(R.string.tickerText);
										contentText = message.username + " is " + message.distance + 
												" meters away and has accepted your request";//Resources.getSystem().getString(R.string.trackingRequest);
	
										theNotificationToShow = new Notification(icon, tickerText, when);
										theNotificationToShow.setLatestEventInfo(MyApplication.getAppContext(), contentTitle, contentText, contentIntent);
										theNotificationToShow.defaults |= Notification.DEFAULT_SOUND;
										theNotificationToShow.defaults |= Notification.DEFAULT_VIBRATE;
										theNotificationToShow.flags |= Notification.FLAG_AUTO_CANCEL;
										contentView.setTextViewText(R.id.textNotify, contentText);
										theNotificationToShow.contentView = contentView;
										notificationManager.notify(1, theNotificationToShow);
										runningIsAllowed = true;
	
										break;
									case DECLINE:
										tickerText = "TrackingDecline";//Resources.getSystem().getString(R.string.tickerText);
										contentText = message.username + " has declined your request.";//Resources.getSystem().getString(R.string.trackingRequest);
	
										theNotificationToShow = new Notification(icon, tickerText, when);
										theNotificationToShow.setLatestEventInfo(MyApplication.getAppContext(), contentTitle, contentText, contentIntent);
										theNotificationToShow.defaults |= Notification.DEFAULT_SOUND;
										theNotificationToShow.defaults |= Notification.DEFAULT_VIBRATE;
										theNotificationToShow.flags |= Notification.FLAG_AUTO_CANCEL;
										contentView.setTextViewText(R.id.textNotify, contentText);
										theNotificationToShow.contentView = contentView;
										notificationManager.notify(1, theNotificationToShow);
										runningIsAllowed = true;
	
										break;
									case TIME:
										tickerText = "Friend on the way";//Resources.getSystem().getString(R.string.tickerText);
										contentText = message.username + " is on the way. " +
												"Estimated time for arrival is in " + message.timeToArrival + " minutes.";//Resources.getSystem().getString(R.string.trackingRequest);
	
										theNotificationToShow = new Notification(icon, tickerText, when);
										theNotificationToShow.setLatestEventInfo(MyApplication.getAppContext(), contentTitle, contentText, contentIntent);
										theNotificationToShow.defaults |= Notification.DEFAULT_SOUND;
										theNotificationToShow.defaults |= Notification.DEFAULT_VIBRATE;
										theNotificationToShow.flags |= Notification.FLAG_AUTO_CANCEL;
										contentView.setTextViewText(R.id.textNotify, contentText);
										theNotificationToShow.contentView = contentView;
										notificationManager.notify(2, theNotificationToShow);
										runningIsAllowed = true;
		
										break;
									default:
										Log.e(TAG, "Got an default AnswerTracking.Type."); //TODO "Got an default AnswerTracking.Type."
								}
							}
							else
							{
								values = new ContentValues();
	
								values.put(Data.C_DATE, new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(sms.getTimestampMillis())).toString());
								values.put(Data.C_SOURCE, sms.getOriginatingAddress());
								values.put(Data.C_SOURCE_NAME, message.username);
								values.put(Data.C_DIRECTION, Data.DIRECTION.INCOMING.name());
	
								Log.d(TAG, "ContentValues created."); //TODO "ContentValues created."
	
	
								Log.d(TAG, "ContentValues saved in the database."); //TODO "ContentValues saved in the database."
							}
							this.abortBroadcast();
							Log.d(TAG, "Broadcast aborted."); //TODO "Broadcast aborted."
	
							if(message.type == null)
							{
								MyApplication.getAppContext();
								//Location stuff
								LocationIdentifier identifier = LocationIdentifier.getInstance((LocationManager) 
										MyApplication.getAppContext().getSystemService(Context.LOCATION_SERVICE));//LocationIdentifier identifier = new LocationIdentifier((LocationManager) MyApplication.getAppContext().getSystemService(Context.LOCATION_SERVICE));
								identifier.startLocationSearching();
								CoordinatesHandler.getCoordinatesHandler().addCoordinatesListener(this);
							}
						}
						catch (DecryptionException e)
						{
							// If this Exception occur it is not ours message.
							Log.d(TAG, "Not our message."); //TODO "Not our message."
							runningIsAllowed = true;
						}
					
					}
				}

			}
		}
		else
		{
			Log.d(TAG, "This service is running already.");
			//quote: "The SMS message is contained and attached to the Intent object (intent --- ) via a Bundle object."
			Bundle extras = intent.getExtras();

			if ( extras != null )
			{
				// Get the received SMS array (Which is the actual SMS saved in a PDU format). quote: "The messages are stored in an Object array in the PDU format"
				// The SMS may be a chained SMS (4 SMS's received as one SMS).
				Object[] smsExtra = (Object[]) extras.get( SMS_EXTRA_NAME );

				if(smsExtra.length==1)
				{
					Log.d(TAG, "Possible SMS received."); //TODO "Possible SMS received."

					SmsMessage sms = SmsMessage.createFromPdu((byte[])smsExtra[0]);
					String test = sms.getMessageBody().toString();
					
					if(test.equalsIgnoreCase(MSG))
					{
						this.abortBroadcast();
					}
				}
			}
		}
	}

	@Override
	public void onNewCoordinates(Coordinates coordinates)
	{
		Log.d(TAG, "Accuracy: " + coordinates.getAccuracyString());
		runningIsAllowed = false;
		if (coordinates.getAccuracy() < BaseActivity.getAccuracy())
		{
			CoordinatesHandler.getCoordinatesHandler().removeCoordinatesListener(this);

			double longitude = coordinates.getLongitude();
			double latitude = coordinates.getLatitude();

			//put coordinates to database
			values.put(Data.C_LONGITUDE_ME, longitude);
			values.put(Data.C_LATITUDE_ME, latitude);
			values.put(Data.C_LONGITUDE_OTHER, message.longitude);
			values.put(Data.C_LATITUDE_OTHER, message.latitude);

			Data data = new Data();
			BaseActivity.setIdOfNewRow(data.insertOrIgnore(values));
			message = null;
			values = null;

			MyApplication.getAppContext();
			NotificationManager notificationManager = (NotificationManager) 
					MyApplication.getAppContext().getSystemService(Context.NOTIFICATION_SERVICE);

			Intent notificationIntent = new Intent(MyApplication.getAppContext(), NotificationActivity.class);
			PendingIntent contentIntent = PendingIntent.getActivity(MyApplication.getAppContext(), 0, notificationIntent, 0);

			int icon = R.drawable.friendtracker_icon;
			CharSequence tickerText = "TrackingRequest";//Resources.getSystem().getString(R.string.tickerText);
			long when = System.currentTimeMillis();
			CharSequence contentTitle = "FriendTracker";//Resources.getSystem().getString(R.string.app_name);
			CharSequence contentText = "Tracking request";//Resources.getSystem().getString(R.string.trackingRequest);

			Notification theNotificationToShow = new Notification(icon, tickerText, when);
			theNotificationToShow.setLatestEventInfo(MyApplication.getAppContext(), contentTitle, contentText, contentIntent);
			theNotificationToShow.defaults |= Notification.DEFAULT_SOUND;
			theNotificationToShow.defaults |= Notification.DEFAULT_VIBRATE;
			theNotificationToShow.flags |= Notification.FLAG_AUTO_CANCEL;

			notificationManager.notify(11, theNotificationToShow);

			Log.i(TAG, "Coordinates fetched, TrackingActivity started");
			Log.d(TAG, "Tracking listener is set up."); //TODO "Tracking listener is set up."
			runningIsAllowed = true;
		}
	}

	@Override
	public boolean isActive()
	{
		return true;
	}
}
